Skip to content

fix(@angular/build): prevent concurrent stylesheet bundling esbuild context leaks#33318

Merged
clydin merged 1 commit into
angular:mainfrom
clydin:fix-esbuild-leak-33317
Jun 8, 2026
Merged

fix(@angular/build): prevent concurrent stylesheet bundling esbuild context leaks#33318
clydin merged 1 commit into
angular:mainfrom
clydin:fix-esbuild-leak-33317

Conversation

@clydin

@clydin clydin commented Jun 5, 2026

Copy link
Copy Markdown
Member

When multiple components in the same file define identical inline styles, concurrent calls to the stylesheet bundler invoke Cache.getOrCreate concurrently with the same key. Because getOrCreate is not concurrency-safe, multiple BundlerContext instances are created.

Additionally, if multiple bundle() requests occur concurrently on a BundlerContext when the esbuild context is not yet initialized, they both invoke context(), causing one to overwrite and leak the other. Leaked esbuild contexts keep the Node event loop active forever, hanging the test runner.

Resolve the Cache race by using an internal Map of in-flight promises to share the same active request, along with a version counter to detect mid-flight writes and safely retry. Resolve the BundlerContext race by memoizing and sharing the active performBundle promise.

Fixes #33317

@clydin clydin added the target: patch This PR is targeted for the next patch release label Jun 5, 2026
@clydin clydin marked this pull request as ready for review June 8, 2026 12:05

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces request deduplication and write tracking to the Cache class to handle concurrent getOrCreate calls safely, alongside improvements to BundlerContext to manage active bundle promises and disposal. The review feedback highlights a potential race condition in Cache.getOrCreate where an active request might be incorrectly deleted after an await gap, a failing assertion in the new unit tests regarding promise resolution after a cache override, and a potential memory leak due to #writeCounts entries never being cleaned up.

Comment thread packages/angular/build/src/tools/esbuild/cache.ts Outdated
Comment thread packages/angular/build/src/tools/esbuild/cache_spec.ts Outdated
Comment thread packages/angular/build/src/tools/esbuild/cache.ts
@clydin clydin force-pushed the fix-esbuild-leak-33317 branch from 983db14 to 01404ec Compare June 8, 2026 13:31
…ontext leaks

When multiple components in the same file define identical inline styles, concurrent calls to the
stylesheet bundler invoke Cache.getOrCreate concurrently with the same key. Because getOrCreate is
not concurrency-safe, multiple BundlerContext instances are created.

Additionally, if multiple bundle() requests occur concurrently on a BundlerContext when the
esbuild context is not yet initialized, they both invoke context(), causing one to overwrite
and leak the other. Leaked esbuild contexts keep the Node event loop active forever, hanging
the test runner.

Resolve the Cache race by using an internal Map of in-flight promises to share the same active
request, along with a version counter to detect mid-flight writes and safely retry. Resolve the
BundlerContext race by memoizing and sharing the active performBundle promise.

Fixes angular#33317
@clydin clydin force-pushed the fix-esbuild-leak-33317 branch from 01404ec to 0c80537 Compare June 8, 2026 13:34
@clydin clydin added the action: review The PR is still awaiting reviews from at least one requested reviewer label Jun 8, 2026
@clydin clydin requested a review from alan-agius4 June 8, 2026 14:01
@alan-agius4 alan-agius4 added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Jun 8, 2026
@clydin clydin merged commit 7786de1 into angular:main Jun 8, 2026
40 checks passed
@clydin

clydin commented Jun 8, 2026

Copy link
Copy Markdown
Member Author

This PR was merged into the repository. The changes were merged into the following branches:

@clydin clydin deleted the fix-esbuild-leak-33317 branch June 8, 2026 14:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action: merge The PR is ready for merge by the caretaker area: @angular/build target: patch This PR is targeted for the next patch release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@angular/build:unit-test hangs forever when two components in one file have identical inline styles

2 participants